import logging as log
from sqlalchemy import inspect
from objprint import objprint



class InspectUtils:
    def __init__(self, engine):
        self.engine = engine
        self.inspector = inspect(self.engine)
        self.__tables = []

    @property
    def tables(self):
        if self.__tables:
            return self.__tables
        with self.engine.connect() as conn:
            inspector = inspect(conn)
            log.info(f"tables: {self.__tables}")
            self.__tables = inspector.get_table_names()
        return self.__tables

    def db_type_to_go_type(self,db_type):
        """
            Convert a database field type to a Go language type.

            Args:
            db_type (str): The database field type.

            Returns:
            str: The corresponding Go language type.
            """
        type_mapping = {
            'INT': 'uint',
            'INTEGER': 'uint',
            'TINYINT': 'uint',
            'SMALLINT': 'uint',
            'MEDIUMINT': 'uint',
            'BIGINT': 'uint',
            'FLOAT': 'float32',
            'DOUBLE': 'float64',
            'DECIMAL': 'float64',
            'BOOLEAN': 'bool',
            'DATE': 'time.Time',
            'DATETIME': '*gtime.Time',
            'TIMESTAMP': '*gtime.Time',
            'VARCHAR': 'string',
            'CHAR': 'string',
            'TEXT': 'string',
            'BLOB': '[]byte',
            'JSON': 'interface{}',  # JSON can be complex, this is a simple placeholder
        }
        log.info(f"db_type: {db_type},result:{type_mapping.get(db_type.upper(), 'interface{}') }")
        return type_mapping.get(db_type.upper(), 'interface{}')  # Default to interface{}

    def convert_to_ts_type(self,db_type):
        type_mapping = {
            'INT': 'number',
            'INTEGER': 'number',
            'TINYINT': 'number',
            'SMALLINT': 'number',
            'MEDIUMINT': 'number',
            'BIGINT': 'number',
            'FLOAT': 'number',
            'DOUBLE': 'number',
            'DECIMAL': 'number',
            'BOOLEAN': 'boolean',
            'DATE': 'string',
            'DATETIME': 'string',
            'TIMESTAMP': 'string',
            'VARCHAR': 'string',
            'CHAR': 'string',
            'TEXT': 'string',
            'BLOB': 'string',
            'JSON': 'string',  # JSON can be complex, this is a simple placeholder
        }
        log.info(f"db_type: {db_type},result:{type_mapping.get(db_type.upper(), 'string') }")
        return type_mapping.get(db_type.upper(), 'string')

    def build_table_info(self,column_info):
        info = {}
        info['name'] = column_info['name']
        column_type = str(column_info['type'])
        if '(' in column_type:
            info['type'] = self.db_type_to_go_type(column_type[:column_type.index('(')])
            info['length'] = int(column_type[column_type.index('(')+1:column_type.index(')')])
            if ',' in column_type:
                info['precision'] = int(column_type[column_type.index(',')+1:column_type.index(')')])
            info['tsType'] = self.convert_to_ts_type(column_type[:column_type.index('(')])
        else:
            log.info(f"column_type: {column_type}")
            info['type'] = self.db_type_to_go_type(column_type)
            info['tsType'] = self.convert_to_ts_type(column_type)
        info['nullable'] = column_info['nullable']
        info['default'] = column_info.get('default', '')
        info['comment'] = column_info.get('comment', '')
        info['autoincrement'] = column_info.get('autoincrement', False)
        # 驼峰名称
        info['camelName'] = info['name'].split('_')[0].lower() + ''.join(word.capitalize() for word in info['name'].split('_')[1:])
        # 首字母名称
        info['firstUpperName'] = info['camelName'][0].upper() + info['camelName'][1:]
        return info

    def get_table_info(self, table_name):
        table_info = []
        with self.engine.connect() as conn:
            inspector = inspect(conn)
            table_infos = inspector.get_columns(table_name)
            for item in table_infos:
                table_info.append(self.build_table_info(item))
        return table_info

    def get_infos(self,table_name):
        info = {}
        table_info = {}
        info['table_info'] = table_info
        # 表信息
        table_info['name'] = table_name
        table_info['camelName'] = table_name.split('_')[0].lower() + ''.join(word.capitalize() for word in table_name.split('_')[1:])
        table_info['firstUpperName'] = table_info['camelName'][0].upper() + table_info['camelName'][1:]
        table_info['comment'] = self.inspector.get_table_comment(table_name).get('text', '')
        table_info['pK'] = self.inspector.get_pk_constraint(table_name).get('constrained_columns', [])
        table_info['fK'] = self.inspector.get_foreign_keys(table_name)
        table_info['index'] = self.inspector.get_indexes(table_name)
        table_info['unique'] = self.inspector.get_unique_constraints(table_name)
        table_info['check'] = self.inspector.get_check_constraints(table_name)

        table_info = self.get_table_info(table_name)
        info['field_info'] = table_info

        objprint(info)
        return info

    def get_file_info(self, table_name):
        info = {'name': table_name,
                'camel_name': table_name.split('_')[0].lower() + ''.join(word.capitalize() for word in table_name.split('_')[1:])}
        info['first_upper_name'] = info['camel_name'][0].upper() + info['camel_name'][1:]
        return info